/*
 * @Author: song
 * @Description: Timline面板
 * @Date: 2024年05月03日 星期五 22:05:11
 * @Modify:
 */

using System;
using System.Collections.Generic;
using Function.SkillEditor.Runtime;
using SCore.Editor.WindowDraw;
using SCore.Function.Fixed;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;

namespace Function.SkillEditor.Editor
{
    public class SkillTimeLineSubWindow : IESubWindow
    {
        private SkillTimeLineMarkerView _markerView; //刻度盘
        private SkillTimeLineCursorView _cursorView; //当前刻度
        private SkillTimeLineTrackView _trackView; //轨道
        private SkillTimeLineHeadView _headView; //标题
        private SkillTimeLineEndCursorView _endCursorView; //长度刻度
        private SkillTimeLineHorScrollBar _scrollBarView; //滚动条

        [Tooltip("被编辑的对象")] public SkillConfigItemData _skillConfigItem;
        [Tooltip("增加轨道弹版")] private GenericMenu _genericMenu;
        [Tooltip("分界线")] private ELineView _eLineView;
        [Tooltip("滚动位置")] private Vector2 _scrollPosition;
        public static GameObject _editorGo;

        private Dictionary<Type, TrackRegisterAttribute> _regAttribute =
            new Dictionary<Type, TrackRegisterAttribute>();

        public SkillTimeLineSubWindow(EditorWindow window) : base(window)
        {
        }


        //---------Lift Function
        public override void OnEnable()
        {
            _regAttribute.Clear();
            _genericMenu = new GenericMenu();
            var regList = SkillTrackDrawerHelper.FindAllTrackRegisters();
            foreach (var reg in regList)
            {
                _genericMenu.AddItem(new GUIContent(reg._addName), false, AddTrack, reg);
                _regAttribute.Add(reg._trackType, reg);
            }

            SkillEditorWindow.EventManager.AddListener<SkillConfigItemData>(SkillEditorEventType.TimeLineEditChange,
                OnTimeLineEditChange);

            SkillEditorWindow.EventManager.AddListener<GameObject>(SkillEditorEventType.EditorGameObjectChange,
                OnEditorGameObjectChange);
            base.OnEnable();
        }


        public override void OnDisable()
        {
            SkillEditorWindow.EventManager.RemoveListener<SkillConfigItemData>(SkillEditorEventType.TimeLineEditChange,
                OnTimeLineEditChange);
            SkillEditorWindow.EventManager.RemoveListener<GameObject>(SkillEditorEventType.EditorGameObjectChange,
                OnEditorGameObjectChange);
            if (_editorGo != null)
            {
                Object.DestroyImmediate(_editorGo);
                _editorGo = null;
            }

            base.OnDisable();
        }

        public override void OnGUI()
        {
            EditorGUI.DrawRect(_rect, EditorDrawHelp.HexToColor("#AAAAAA"));
            if (_skillConfigItem == null || _skillConfigItem._skillRunLine == null)
            {
                if (_skillConfigItem == null)
                {
                    GUILayout.Label("请选择需要编辑的选项",
                        EditorDrawHelp.GetTextGUIStyle(18, TextAnchor.MiddleCenter, EditorDrawHelp._tanBrown));
                    return;
                }

                DrawCreateLineButton();
            }
            else
            {
                using (new GUILayout.VerticalScope())
                {
                    //head区域
                    using (new GUILayout.HorizontalScope(EditorStyles.toolbar))
                    {
                        _headView.OnHeadGUI();
                    }

                    //刻度
                    using (new GUILayout.HorizontalScope(EditorStyles.toolbar))
                    {
                        //刻度左边区域
                        using (new GUILayout.VerticalScope(GUILayout.Width(_eLineView.GetCurPercent() * _rect.width)))
                        {
                            if (EditorGUILayout.DropdownButton(EditorContentHelp.NewContent, FocusType.Passive,
                                    EditorStyles.toolbarPopup))
                            {
                                _genericMenu.ShowAsContext();
                            }
                        }

                        //计算 marker区域
                        var dropDownArea = GUILayoutUtility.GetLastRect();
                        if (dropDownArea != Rect.zero && dropDownArea != new Rect(0, 0, 1, 1))
                        {
                            _markerView.UpdateArea(new Rect(dropDownArea.xMax, dropDownArea.y,
                                _rect.width - dropDownArea.width,
                                _rect.height));
                            EditorGUI.DrawRect(
                                new Rect(dropDownArea.xMax, dropDownArea.y, _rect.width - dropDownArea.width,
                                    dropDownArea.height), EditorDrawHelp.HexToColor("#CBCBCB"));
                        }

                        _markerView.OnMarkerGUI();
                    }

                    //skillTrack
                    using (var scrollViewScope = new GUILayout.ScrollViewScope(_scrollPosition, false, false,
                               GUILayout.ExpandWidth(
                                   true), GUILayout
                                   .ExpandHeight(true)))
                    {
                        _scrollPosition = scrollViewScope.scrollPosition;
                        using (new GUILayout.VerticalScope())
                        {
                            _trackView.OnTrackGUI();
                        }
                    }

                    var area = GUILayoutUtility.GetLastRect();
                    if (area != Rect.zero && area != new Rect(0, 0, 1, 1))
                    {
                        area = new Rect(0, 0, area.width, area.height);
                        _trackView.UpdateArea(area);
                    }

                    GUILayout.FlexibleSpace();
                    using (new GUILayout.HorizontalScope(GUILayout.ExpandWidth(true)))
                    {
                        GUILayout.Space(_rect.width * _eLineView.GetCurPercent());
                        _scrollBarView.OnScrollBarGUI();
                    }
                }

                var rect = _markerView.GetRect();
                EditorClip.Push(new Rect(rect.x, rect.y, rect.width - _markerView.GetZeroFrameWidth(), rect.height));
                _cursorView.OnCursorGUI();
                _endCursorView.OnEndCursorGUI();
                EditorClip.Pop();
                base.OnGUI();
            }
        }

        protected override List<ICommonView> BindView()
        {
            //创建子界面
            var bindViews = SkillEditorConfig.Instance.GetWindowConfig(SkillWindowType.TimeLine);
            _eLineView = bindViews._eCommonViews[0] as ELineView;
            if (_markerView == null)
            {
                _markerView = new SkillTimeLineMarkerView();
            }

            if (_endCursorView == null)
            {
                _endCursorView = new SkillTimeLineEndCursorView();
            }

            if (_headView == null)
            {
                _headView = new SkillTimeLineHeadView();
            }

            if (_cursorView == null)
            {
                _cursorView = new SkillTimeLineCursorView();
            }

            if (_trackView == null)
            {
                _trackView = new SkillTimeLineTrackView();
            }

            if (_scrollBarView == null)
            {
                _scrollBarView = new SkillTimeLineHorScrollBar();
            }

            //设置子界面
            _eLineView.SetUp(this);
            _markerView.SetUp(this);
            _endCursorView.SetUp(this);
            _headView.SetUp(this);
            _cursorView.SetUp(this);
            _trackView.SetUp(this);
            _scrollBarView.SetUp(this);
            _markerView.Bind(_eLineView);
            _endCursorView.Bind(_markerView);
            _headView.Bind(_cursorView);
            _cursorView.Bind(_markerView, _headView);
            _trackView.Bind(_markerView, _eLineView, _headView, _cursorView);
            _scrollBarView.Bind(_markerView, _eLineView);

            var resultViews = new List<ICommonView>();
            foreach (var bindView in bindViews._eCommonViews)
            {
                resultViews.Add(bindView);
            }

            resultViews.Add(_markerView);
            resultViews.Add(_cursorView);
            resultViews.Add(_trackView);
            resultViews.Add(_headView);
            resultViews.Add(_endCursorView);
            resultViews.Add(_scrollBarView);
            return resultViews;
        }

        //-------------Draw
        private void DrawCreateLineButton()
        {
            GUILayout.FlexibleSpace();
            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("创建SkillLine",
                    EditorDrawHelp.GetButtonGUIStyle(18, TextAnchor.MiddleCenter, EditorDrawHelp._tanBrown),
                    GUILayout.Width(200)))
            {
                if (_skillConfigItem != null)
                {
                    _skillConfigItem._skillRunLine =
                        SkillEditorConfig.Instance.CreateSkillRunLine(_skillConfigItem._id);
                }
            }

            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();
            GUILayout.FlexibleSpace();
        }

        //---------Handle
        private void OnTimeLineEditChange(SkillConfigItemData skillConfigItemData)
        {
            _cursorView._curFrame = fp.Zero;
            if (_editorGo != null)
            {
                Object.DestroyImmediate(_editorGo);
                _editorGo = null;
            }


            _skillConfigItem = skillConfigItemData;
            if (skillConfigItemData != null)
            {
                Dictionary<SkillClip, SkillClip> clipSaveMap = new Dictionary<SkillClip, SkillClip>();

                var skillRunLine = skillConfigItemData._skillRunLine;
                if (skillRunLine != null &&
                    !skillRunLine.name.Contains("Clone"))
                {
                    var cloneRunLine = Object.Instantiate(skillConfigItemData._skillRunLine);
                    skillConfigItemData._skillRunLine = cloneRunLine;
                    for (int offest = cloneRunLine._skillTracks.Count - 1; offest >= 0; offest--)
                    {
                        var copySkillTrack = Object.Instantiate(cloneRunLine._skillTracks[offest]);
                        cloneRunLine._skillTracks[offest] = copySkillTrack;
                        for (int clipOffest = copySkillTrack.GetClips().Count - 1; clipOffest >= 0; clipOffest--)
                        {
                            var clipObject = Object.Instantiate(copySkillTrack.GetClipByIndex(clipOffest));
                            clipSaveMap.Add(copySkillTrack.GetClips()[clipOffest], clipObject);
                            copySkillTrack.GetClips()[clipOffest] = clipObject;
                        }
                    }

                    for (int offest = cloneRunLine._skillTracks.Count - 1; offest >= 0; offest--)
                    {
                        var skillTrack = cloneRunLine._skillTracks[offest];
                        if (skillTrack is SkillBuffTrack)
                        {
                            for (int clipOffest = skillTrack.GetClips().Count - 1; clipOffest >= 0; clipOffest--)
                            {
                                SkillBuffClip skillClip = skillTrack.GetClipByIndex(clipOffest).As<SkillBuffClip>();
                                List<SkillTriggerClip> saveClips = new List<SkillTriggerClip>();
                                foreach (var triggerClip in skillClip._triggers)
                                {
                                    saveClips.Add(clipSaveMap[triggerClip] as SkillTriggerClip);
                                }

                                skillClip._triggers = saveClips;
                            }
                        }
                    }
                }

                if (_skillConfigItem._editorGo != null)
                {
                    _editorGo = Object.Instantiate(_skillConfigItem._editorGo);
                }
            }
        }

        private void OnEditorGameObjectChange(GameObject editorGo)
        {
            if (_editorGo != null)
            {
                Object.DestroyImmediate(_editorGo);
                _editorGo = null;
            }

            if (editorGo != null)
            {
                _editorGo = Object.Instantiate(_skillConfigItem._editorGo);
            }
        }

        private void AddTrack(object userdata)
        {
            var reg = userdata as TrackRegisterAttribute;
            SkillEditorConfig.Instance.CreateSkillTrack(reg._trackType, _skillConfigItem._skillRunLine);
        }


        public TrackRegisterAttribute GetRegAttribute(Type type)
        {
            _regAttribute.TryGetValue(type, out var reg);
            return reg;
        }
    }
}